package com.example.nextgen.parser.excel;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.cell.CellUtil;
import com.example.nextgen.function.CommentFunction;
import com.example.nextgen.parser.excel.model.CellModel;
import com.example.nextgen.parser.excel.model.DataType;
import com.example.nextgen.parser.excel.model.ExcelParserResult;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ExcelParser {

    private static final String SHEET_01_NAME = "NEXT";
    private static final String SHEET_02_NAME = "Config";

    private ExcelParser() {
    }

    public static ExcelParserResult parse(ExcelReader excelReader) {
        List<Sheet> sheets = excelReader.getSheets();
        ExcelParserResult result = new ExcelParserResult();
        result.setConfig(extractSheetData(sheets.get(1)));
        ExcelContext.putExcel(result);
        result.setDevelopForms(extractSheetData(sheets.get(0)));
        result.refreshConfigFromFroms();
        List<Sheet> templateSheets = sheets.subList(2, sheets.size());
        result.setTemplateSheets(templateSheets);
        result.setExcelReader(excelReader);
        return result;
    }

    private static Map<String, Object> extractSheetData(Sheet sheet) {
        Map<String, CellModel> modelMap = new LinkedHashMap<>();
        Map<String, Object> data = new LinkedHashMap<>();
        sheet.rowIterator().forEachRemaining(row -> {
            row.cellIterator().forEachRemaining(cell -> {
                ((XSSFCell)cell).setCellType(CellType.STRING);
                String cellValue = cell.getStringCellValue();
                if (StrUtil.isBlank(cellValue)) {
                    return;
                }
                CellModel cellModel = new CellModel();
                cellModel.setContent(cellValue);
                cellModel.setColumnIndex(cell.getColumnIndex());
                cellModel.setRowIndex(cell.getRowIndex());
                cellModel.setBold(((XSSFCellStyle) cell.getCellStyle()).getFont().getBold());
                cellModel.setMerged(CellUtil.isMergedRegion(cell));
                cellModel.setTop(modelMap.get(cellModel.getTopAddress()));
                cellModel.setLeft(modelMap.get(cellModel.getLeftAddress()));
                cellModel.setContent(cellValue);
                if (cell.getCellComment() != null) {
                    cellModel.setComment(cell.getCellComment().getString().getString());
                    Object result = SpringUtil.getBean(CommentFunction.class).getFunctionResult(cellModel);
                    cellModel.setContent(result);
                }
                modelMap.put(cellModel.getAddress(), cellModel);
            });
        });
        modelMap.values().stream().filter(cellModel -> cellModel.getRoot() == cellModel)
                .forEach(rootCell -> data.putAll(DataType.extractData(rootCell)));
        return data;
    }

    public static boolean checkExcelIsValid(ExcelReader excelReader) {
        Sheet developFormsSheet = excelReader.getSheets().get(0);
        Sheet configSheet = excelReader.getSheets().get(1);
        return SHEET_01_NAME.equals(developFormsSheet.getSheetName())
                && SHEET_02_NAME.equals(configSheet.getSheetName());
    }
}
